﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web.Hosting;
using System.Web.WebPages;
using System.Xml.Linq;

namespace Exocortex.Excel.Nuget
{
    public class PackageSourceFile : IPackagesSourceFile
    {
        private readonly string _fileName;
        private const string FilterPreferredAttribute = "filterpreferred";
        private const string NameAttribute = "displayname";
        private const string UrlAttribute = "url";

        public PackageSourceFile(string fileName)
        {
            this._fileName = fileName;
        }

        public bool Exists()
        {
            return HostingEnvironment.VirtualPathProvider.FileExists(this._fileName);
        }

        private Stream GetStreamForRead()
        {
            return HostingEnvironment.VirtualPathProvider.GetFile(this._fileName).Open();
        }

        private Stream GetStreamForWrite()
        {
            string path = HostingEnvironment.MapPath(this._fileName);
            if (!File.Exists(this._fileName))
            {
                Directory.CreateDirectory(Path.GetDirectoryName(path));
                return File.Create(path);
            }
            return File.Open(path, FileMode.Truncate);
        }

        public static WebPackageSource ParsePackageSource(XElement element)
        {
            Uri uri;
            XAttribute attribute = element.Attribute("url");
            XAttribute attribute2 = element.Attribute("displayname");
            XAttribute attribute3 = element.Attribute("filterpreferred");
            if ((attribute == null) || (attribute2 == null))
            {
                throw new FormatException();
            }
            if (!Uri.TryCreate(attribute.Value, UriKind.Absolute, out uri))
            {
                throw new FormatException();
            }
            WebPackageSource source = new WebPackageSource(uri.OriginalString, attribute2.Value);
            source.FilterPreferredPackages = (attribute3 != null) && attribute3.Value.AsBool(false);
            return source;
        }

        public static IEnumerable<WebPackageSource> ReadFeeds(Func<Stream> getStream)
        {
            using (Stream stream = getStream())
            {
                return XDocument.Load(stream).Root.Elements().Select<XElement, WebPackageSource>(delegate (XElement element) {
                    return ParsePackageSource(element);
                }).ToList<WebPackageSource>();
            }
        }

        public IEnumerable<WebPackageSource> ReadSources()
        {
            return ReadFeeds(delegate {
                return this.GetStreamForRead();
            });
        }

        public static void WriteFeeds(IEnumerable<WebPackageSource> sources, Func<Stream> getStream)
        {
            IEnumerable<XElement> content = sources.Select<WebPackageSource, XElement>(delegate (WebPackageSource item) {
                return new XElement("source", new object[] { new XAttribute("url", item.Source), new XAttribute("displayname", item.Name), new XAttribute("filterpreferred", item.FilterPreferredPackages) });
            });
            using (Stream stream = getStream())
            {
                new XDocument(new object[] { new XElement("sources", content) }).Save(stream);
            }
        }

        public void WriteSources(IEnumerable<WebPackageSource> sources)
        {
            WriteFeeds(sources, delegate {
                return this.GetStreamForWrite();
            });
        }
    }
}

